package FrequentSequenceMining;

import java.util.ArrayList;

public class Sequence implements Comparable {
	private ArrayList<String> sequence;
	private ArrayList<Integer> appearsIn;
	private int support;
	private Sequence parent1;
	private Sequence parent2;
	
	public Sequence() {
		sequence = new ArrayList<String>();
		appearsIn = new ArrayList<Integer>();
	}
	
	public Sequence(ArrayList<String> seq, Sequence p1, Sequence p2) {
		this();
		sequence = seq;
		parent1 = p1;
		parent2 = p2;
		calculateFrequency();
	}
	
	public Sequence(String word) {
		this();
		sequence.add(word);
		support = 1;
	}
	
	public void addAppearance(int line) {
		appearsIn.add(line);
	}
	
	public void increaseSupport() {
		support++;
	}

	private void calculateFrequency() {
		support = 0;
		ArrayList<ArrayList<String>> sentences = Data.getInstance().getSentences();
		//we only look at sentences where first parent appears
//		Sequence firstWordSeq = Data.getInstance().getCorrespondingSequence(sequence.get(0));
		for(int index:parent1.appearsIn) {
			ArrayList<String> sentence = sentences.get(index);
			//System.out.println(sequence.get(0) + " - " + sentence + " - " + index);
			int x = countAppearances(sentence);
			if(x > 0) {
				appearsIn.add(index);
				support += x;
			}
		}
	}

	private int countAppearances(ArrayList<String> sentence) {
		int count = 0;
		int maxStartingPosition = sentence.size()-sequence.size();
		for(int i = 0; i <= maxStartingPosition; ++i) {
			if(sequenceMatchesSubsentence(sentence, i)) {
				++count;
			}
		}
		return count;
	}

	private boolean sequenceMatchesSubsentence(ArrayList<String> sentence, int startIndex) {
		for(int i = 0; i < sequence.size(); ++i) {
			if(!(sequence.get(i).equals(sentence.get(startIndex+i)))) {
				return false;
			}
		}
		return true;
	}
	
	public ArrayList<String> getSequence() {
		return sequence;
	}
	
	public ArrayList<String> getSequenceCopy() {
		ArrayList<String> copy = new ArrayList<String>(sequence);
		return copy;
	}

	@Override
	public int compareTo(Object o) {
		if(!(o instanceof Sequence)) return -1;
		return support - ((Sequence)o).support;
	}
	
	@Override
	public String toString() {
		String toRet = "";
		for(String s:sequence) {
			toRet += s +" ";
		}
		return toRet;
	}

	public int getSupport() {
		return support;
	}

	public double getFrequency() {
		return (double)support/Data.getInstance().getTotalSentences();
	}

	public Sequence mergeWith(Sequence s2) {
		ArrayList<String> seq2 = s2.getSequence();
		ArrayList<String> newseq = new ArrayList<String> (sequence);
		newseq.add(seq2.get(seq2.size()-1));
		Sequence result = new Sequence(newseq, this, s2);
		return result;
	}
}
